/**
 * 包含n个action creator
 * 同步action
 * 异步action
 */
import io from 'socket.io-client'
import { reqChatMsgList, reqLogin, reqRegister, reqUpdataUser, reqUser, reqUserList, reqReadMsg } from "../api"
import {AUTH_SUCCESS, ERROR_MSG, RECEIVE_USER, RESET_USER, RECEIVE_USER_LIST, RECEIVE_MSG_LIST, RECEIVE_MSG, MSG_READ } from './action-types'

// 授权成功的同步action
const authSucess = (user)=> ({type: AUTH_SUCCESS, data: user})
// 错误提示信息的同步action
const errorMsg = (msg)=>({type: ERROR_MSG, data: msg})
//  接收用户的同步action
const receiveUser = (user) =>({type: RECEIVE_USER, data:user})
// 重置用户的同步action
export const resetUser = (msg)=>({type: RESET_USER, data: msg})
// 接收用户列表的同步action
export const receiveUserList = (userList) =>({type: RECEIVE_USER_LIST, data: userList})
// 接收消息列表同步任务
export const receiveMsgList = ({users, chatMsgs, userId}) =>({type: RECEIVE_MSG_LIST, data:{users, chatMsgs, userId}})
// 接收一个消息的同步action
export const receiveMsg = (chatMsg, userId) =>({type: RECEIVE_MSG, data: {chatMsg, userId}})
// 读取了某个聊天消息的同步action
const msgRead = ({count, from, to}) => ({type: MSG_READ, data: {count, from, to}})

// 注册异步action
// 异步action中第1个参数叫dispatch，第2个参数是getState
// 在异步action中就可以写异步代码
// 在异步代码，还需要派发一个同步的action
export const register = (user) =>{
    const {username, password, password2, type} = user
    if(!username){
        return errorMsg('请输入用户名')
    }
    if(password !== password2){
        return errorMsg ('两次密码要一致')
    }
    return async dispatch =>{
        // 发送注册的异步Ajax请求
        // 不加await获得的是一个promise， await可以直接得到结果
        const response = await reqRegister({username, password, type})
        const result = response.data
        const userId = result.data._id
        if(result.code === 0){  // 成功
            getMsgList(dispatch, userId)
            // 分发成功action
            dispatch(authSucess(result.data)) 
        } else{     // 失败
            // 分发失败的action
            dispatch(errorMsg(result.msg))
        }
    }
}

// 登录异步action
export const login = (user) =>{
    const {username, password} = user
    if(!username){
        return errorMsg('请输入用户名')
    }
    if(!password){
        return errorMsg('请输入密码')
    }
    return async dispatch =>{
        // 发送注册的异步Ajax请求
        // 不加await获得的是一个promise， await可以直接得到结果
        const response = await reqLogin(user)
        
        const result = response.data
        if(result.code === 0){  // 成功
            const userId = result.data._id
            getMsgList(dispatch, userId)
            // 分发成功action
            dispatch(authSucess(result.data)) 
        } else{     // 失败
            // 分发失败的action
            dispatch(errorMsg(result.msg))
        }
    }
}

// 更新用户异步action
export const updateUser = (user) =>{
    return async dispatch =>{
        const response = await reqUpdataUser(user)
        const result = response.data
        if(result.code === 0){
            dispatch(receiveUser(result.data))
        }else{
            dispatch(resetUser(result.msg))
        }
    }
}

// 获取用户异步action
export const getUser = ()=>{
    return async dispatch => {
        const respose = await reqUser()
        const result = respose.data
        const userId = result.data._id
        if(result.code === 0){
            getMsgList(dispatch, userId)
            dispatch(receiveUser(result.data))
        }else{
            dispatch(resetUser(result.msg))
        }
    }
}

// 获取用户列表的异步action
export const getUserList = (type) => {
    return async dispatch => {
        const response = await reqUserList(type)
        const result = response.data
        if(result.code === 0){
            dispatch(receiveUserList(result.data))
        }
    } 
}

/**
 * 单例对象：
 *  1. 创建对象之前，判断对象是否已经存在，只有不存在才去创建
 *  2. 创建对象之后：保存对象
 */
function initIO(dispatch, userId) {
    if (!io.socket) {
      io.socket = io('ws://localhost:4000')
   
      io.socket.on('connect',  ()=> {
        console.log('socketio已连接:', io.socket.id)
      })
      
      io.socket.on('receiveMsg', function (chatMsg) {
        
        
        if(chatMsg.from === userId || chatMsg.to === userId){
            console.log('客户端收到消息')
            dispatch(receiveMsg(chatMsg, userId))
        }
    })
        
    }
    // console.log('socketio已连接:')
   
}

// 发送聊天消息
export const sendMsg = ({from, to, content}) =>{
    return dispatch =>{
        io.socket.emit('sendMsg', {from, to, content})
    }
}
// 读取消息的异步action
export const readMsg = (from, to) => {
    return async dispatch => {
      const response = await reqReadMsg(from)
      const result = response.data
      if(result.code===0) {
        const count = result.data
        dispatch(msgRead({count, from, to}))
      }
    }
  }

// 异步获取消息列表
const getMsgList = async (dispatch, userId)=>{
        console.log('初始化ScketIO')
        const response = await reqChatMsgList()
        const result = response.data
        const {users, chatMsgs} = result.data
        if(result.code === 0){ 
            initIO(dispatch, userId)
            dispatch(receiveMsgList({users, chatMsgs, userId}))
        }
    
}



